package org.scboy.dbms.service.imp;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Date;

import org.scboy.coobi.sql.factory.EntityFactory;
import org.scboy.dbms.dao.BaseAppConfigDao;
import org.scboy.dbms.dao.BaseAppServerDao;
import org.scboy.dbms.dao.BaseServersDao;
import org.scboy.dbms.enums.DocType;
import org.scboy.dbms.service.BaseAppConfigService;
import org.scboy.dbms.sftp.SftpClient;
import org.scboy.dbms.utils.ConfigUtil;
import org.scboy.utils.entitys.coobi.Model;
import org.scboy.utils.entitys.coobi.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;

@Service
public class BaseAppConfigServiceImpl implements BaseAppConfigService {

	@Autowired
	EntityFactory factory;
	
	@Override
	public Page page(Model params) {
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		return dao.page(params.addNrc("configValue"));
	}

	@Override
	public boolean add(Model params) {
		BaseAppConfigDao dao = factory.getDao(BaseAppConfigDao.class);
		params.add("id", UUID.randomUUID().toString());
		int count=dao.insert(params);
		if(count>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public boolean delete(String id) {
		
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		
		//检查配置是否启用
		long activityCount=dao.count(Model.create().add("id", id).add("activity", 1));
		if(activityCount>0) {
			return false;
		}
		
		int count=dao.delete(Model.create().add("id", id));
		if(count>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public boolean update(Model params) {
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		int count=dao.update(params);
		if(count>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public Model get(String id) {
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		return dao.get(Model.create().add("id", id));
	}

	@Override
	@Transactional
	public boolean active(String id) {
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		Model data=dao.get(Model.create().add("id", id).addRc("appName"));
		if(data==null) {
			return false;
		}
		
		String appName=data.getString("appName");
		
		//关闭所有的激活状态
		dao.update(Model.create().add("activity", 0),Model.create().add("appName", appName));
		
		int count=dao.update(Model.create().add("id", id).add("activity", 1));
		if(count>0) {
			return true;
		}else {
			return false;
		}
	}
	
	/**
	 * 上传配置文件
	 * @param configId 配置ID
	 * @param appServerId 部署ID
	 */
	@Override
	public String uploadConfig(String configId,String appServerId) {
		BaseAppConfigDao dao=factory.getDao(BaseAppConfigDao.class);
		BaseServersDao serverDao=factory.getDao(BaseServersDao.class);
		BaseAppServerDao appServerDao=factory.getDao(BaseAppServerDao.class);
		
		Model config = dao.get(Model.create().add("id", configId).addRc("appName"));
		
		Model appServer = appServerDao.get(Model.create().add("id", appServerId));
		
		Model server = serverDao.get(Model.create().add("ip", appServer.getString("ip")));
		
		//部署IP
		String ip=appServer.getString("ip");
		
		//部署端口
		int port=appServer.getInt("port");
		
		//部署路径
		String path=appServer.getString("deploymentPath");
		
		//微服务名称
		String appName=appServer.getString("appName");
		
		//部署路径
		path=path + "/"+appName+"-"+port;
		
		//配置文件内容
		String configValue=config.getString("configValue");
		
		//配置文件类型
		String docType=config.getString("docType");
		
		//改变端口
		ConfigUtil configUtil =null;
		if("yml".equals(docType)) {
			configUtil = ConfigUtil.load(configValue, DocType.YAML);
		}else {
			configUtil = ConfigUtil.load(configValue, DocType.PROPERTIES);
		}
		configUtil.setValue("server.port", port+"");
		configValue=configUtil.text();
		
		//管理端口
		Integer serverPort= server.getInt("port");
		//管理账号
		String user= server.getString("adminAccount");
		//管理密码
		String password= server.getString("adminPassword");
		
		if(serverPort==null) {
			serverPort=22;
		}
		
		SftpClient client=null;
		try {
			client=new SftpClient(ip, serverPort, user, password);
		} catch (Exception e) {
			return ExceptionUtil.stacktraceToString(e);
		}
		
		//上传配置文件
		try {
			//检查文件路径是否存在
			boolean dirExist= client.isDirExist(path);
			if(!dirExist) {
				client.mkdirs(path);
			}
			//判断配置文件是否存在
			boolean configExist=client.fileExist(path, "application.properties");
			if(configExist) {
				String oldConfigFile=path+"/"+"application.properties";
				String backConfigFile=path+"/"+"application-"+DateUtil.format(new Date(), "yyyyMMddHHmmss")+".bak";
				client.rename(oldConfigFile, backConfigFile);
			}
			
			InputStream input=IoUtil.toStream(configValue, Charset.defaultCharset());
			client.upload(path, "application.properties", input);
			client.close();
			return "true";
		} catch (IOException e) {
			client.close();
			return ExceptionUtil.stacktraceToString(e);
		}
	}
	
}
